SSH Hardening
Practical SSH server hardening guidance for Linux systems in homelab and self-hosted environments
Introduction
SSH is the primary administrative entry point for many Linux systems. Hardening it reduces the likelihood of credential attacks, accidental privilege exposure, and overly broad remote access.
Purpose
This guide focuses on making SSH safer by:
- Disabling weak authentication paths
- Reducing exposure to brute-force attacks
- Limiting which users can log in
- Preserving maintainability by relying on modern OpenSSH defaults where possible
Architecture Overview
SSH hardening has three layers:
- Transport and daemon configuration
- Network exposure and firewall policy
- Operational practices such as key handling and logging
For most self-hosted systems, the best model is:
Admin workstation -> VPN or trusted network -> SSH serverStep-by-Step Guide
1. Use key-based authentication
Generate a key on the client and copy the public key to the server:
ssh-keygen -t ed25519 -C "admin@example.com"
ssh-copy-id admin@server.example2. Harden sshd_config
Baseline example:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
AllowUsers adminIf you need port forwarding for a specific workflow, enable it deliberately instead of leaving it broadly available.
3. Validate the configuration
sudo sshd -t4. Reload safely
Keep an existing SSH session open while reloading:
sudo systemctl reload sshdDistribution-specific service names may be ssh or sshd.
5. Restrict network exposure
- Prefer VPN-only or management-VLAN-only access
- Allow SSH from trusted subnets only
- Do not expose SSH publicly unless it is necessary and monitored
Configuration Example
Example host firewall intent:
Allow TCP 22 from 192.168.10.0/24
Allow TCP 22 from Tailscale tailnet range
Deny TCP 22 from all other sourcesTroubleshooting Tips
Locked out after config change
- Keep the original session open until a new login succeeds
- Validate the daemon config with
sshd -t - Check the service name and logs with
journalctl -u sshdorjournalctl -u ssh
Key authentication fails
- Check file permissions on
~/.sshandauthorized_keys - Confirm the server allows public key authentication
- Verify the client is offering the intended key with
ssh -v
Automation jobs break
- Review whether the workload depended on password auth, port forwarding, or agent forwarding
- Create narrowly scoped exceptions rather than reverting the whole hardening change
Best Practices
- Rely on current OpenSSH defaults for ciphers and algorithms unless you have a specific compliance need
- Disable password-based interactive logins on internet-reachable systems
- Use individual user accounts and
sudoinstead of direct root SSH - Combine SSH hardening with network-level restrictions
- Review SSH logs regularly on administrative systems